package com.chuangs.custom.incise;

import com.alibaba.fastjson.JSONObject;
import com.chuangs.custom.entity.CustomSystemUserEntity;
import com.chuangs.custom.entity.aspect.CustomSystemLogAspect;
import com.chuangs.custom.utils.IPUtils;
import com.chuangs.custom.utils.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * Work happily and live happily ~~
 *
 * @Description: 系统日志，切面处理类
 * @Author: java开发-袁松
 * @Date: 2023/3/13
 **/
@Aspect
@Component
@Slf4j
public class CustomAutoLogAspect {

/*    @Autowired
    private ISysLogService sysLogService;*//*业务层 */

    @Pointcut("@annotation(com.chuangs.custom.incise.CustomAutoLogIncise)")
    public void logPointCut() {

    }


    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        //保存日志
        saveSysLog(point, time);

        return result;
    }

    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        CustomSystemLogAspect sysLog = new CustomSystemLogAspect();
        CustomAutoLogIncise syslog = method.getAnnotation(CustomAutoLogIncise.class);
        if (syslog != null) {
            //注解上的描述,操作日志内容
            sysLog.setLog_Content(syslog.value());
            sysLog.setLog_Type(syslog.logType());

        }

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
         log.error("请求方法"+className + "." + methodName + "()");

        //设置操作类型
        if (sysLog.getLog_Type() == CustomCommonConstantIncise.LOG_TYPE_2) {
            sysLog.setOperate_Type(getOperateType(methodName, syslog.operateType()));
        }

        //请求的参数
        Object[] args = joinPoint.getArgs();
        try {
            String params = JSONObject.toJSONString(args);
            sysLog.setRequest_Params(params);
        } catch (Exception e) {

        }
        try {
            //获取request
            HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
            //设置IP地址
            sysLog.setIp(IPUtils.getIpAddr(request));
        } catch (Exception e) {

        }
        //获取登录用户信息
        CustomSystemUserEntity sysUser =  new CustomSystemUserEntity();
     /*   try {*/
            /*获取 用户这个对象 用户一登录 就获取用户的信息
            * 在这里获取用户的信息 用户还没请求dologin 之前就访问这 有bug
            * 自定义设置一个用户基本信息容器
            *  模拟数据库数据
            *  */
          sysUser.setId((long) 1001);
          sysLog.setUser_Name("袁松");
          sysUser.setReal_Name("测试用户");

     /*   } catch (Exception e) {

        }*/
        if (sysUser != null) {
            sysLog.setUser_Id((long) 1001);
            sysLog.setUser_Name("袁松");
            sysLog.setReal_Name("测试用户");
        /*    sysLog.setOrgId(sysUser.getNowOrgId());
            sysLog.setOrgName(sysUser.getNowOrgName());*/
        }
        //耗时
        sysLog.setCost_Time(time);
        sysLog.setCreate_Time(new Date());



        //保存系统日志 用打印代替
     //   sysLogService.save(sysLog);
        log.debug(sysLog.toString());
        log.info(sysLog.toString());
    }

    /**
     * 获取操作类型
     */
    private int getOperateType(String methodName, int operateType) {
        if (operateType > 0) {
            return operateType;
        }
        if (methodName.startsWith("list")) {
            return CustomCommonConstantIncise.OPERATE_TYPE_LT2_1;
        }
        if (methodName.startsWith("add")) {
            return CustomCommonConstantIncise.OPERATE_TYPE_LT2_2;
        }
        if (methodName.startsWith("edit")) {
            return CustomCommonConstantIncise.OPERATE_TYPE_LT2_3;
        }
        if (methodName.startsWith("delete")) {
            return CustomCommonConstantIncise.OPERATE_TYPE_LT2_4;
        }
        if (methodName.startsWith("import")) {
            return CustomCommonConstantIncise.OPERATE_TYPE_LT2_5;
        }
        if (methodName.startsWith("export")) {
            return CustomCommonConstantIncise.OPERATE_TYPE_LT2_6;
        }
        return CustomCommonConstantIncise.OPERATE_TYPE_LT2_1;
    }

    @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        CustomSystemLogAspect sysLog = new CustomSystemLogAspect();

        StackTraceElement[] stackTraceElements = ex.getStackTrace();
        String rootExceptionName = ex.getClass().getName();

        StringBuilder resultContent = new StringBuilder("异常类：" + rootExceptionName);

        int count = 0;
        int maxTrace = 3;
        for (StackTraceElement stackTraceElement : stackTraceElements) {
            if (stackTraceElement.getClassName().contains("com.lingxu") && count < maxTrace) {
                resultContent.append("\n出现于").append(stackTraceElement.getClassName())
                        .append("类中的").append(stackTraceElement.getMethodName())
                        .append("方法中 位于该类文件的第").append(stackTraceElement.getLineNumber())
                        .append("行)");
                count++;
                if (count == maxTrace) {
                    break;
                }
            }
        }


        sysLog.setException_Content(resultContent.toString());

        CustomAutoLogIncise syslog = method.getAnnotation(CustomAutoLogIncise.class);


        if (syslog != null) {
            //注解上的描述,操作日志内容
            sysLog.setLog_Content(syslog.value() + "出现异常");
            sysLog.setLog_Type(CustomCommonConstantIncise.LOG_TYPE_4);
        }

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");


        //设置操作类型
        sysLog.setOperate_Type(CustomCommonConstantIncise.OPERATE_TYPE_LT4_1);

        //请求的参数
        Object[] args = joinPoint.getArgs();
        try {
            String params = JSONObject.toJSONString(args);
            sysLog.setRequest_Params(params);
        } catch (Exception e) {

        }
        try {
            //获取request
            HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
            //设置IP地址
            sysLog.setIp(IPUtils.getIpAddr(request));
        } catch (Exception e) {

        }
        try {
            //获取登录用户信息
            CustomSystemUserEntity sysUser = new CustomSystemUserEntity();
            sysUser.setId((long) 1001);
            sysLog.setUser_Name("袁松");
            sysUser.setReal_Name("测试用户");
            if (sysUser != null) {
                sysLog.setUser_Id(sysUser.getId());
                sysLog.setUser_Name(sysUser.getUser_Name());
                sysLog.setReal_Name(sysUser.getReal_Name());
               /* sysLog.setOrgId(sysUser.getNowOrgId());
                sysLog.setOrgName(sysUser.getNowOrgName());*/

            }
        } catch (Exception e) {
        }
        //保存系统日志用日志打印代替
       // sysLogService.save(sysLog);
        log.debug(sysLog.toString());
    }
}

